<template>
	<div class="appContainer">
		<!-- pages -->
		<block v-for="(item, index) in pageData.conData" :key="item.cid">
			<div class="pageCon" :class="{show: currentPageIndex === index}">
				<div class="pageBg" :style="item.pageBg" :class="{tile:item.bgMode==='tile'}"></div>
				<!-- 导航栏 -->
				<block v-for="navbar in item.page.navbar" :key="navbar.cid" v-show="!navbar.common.isHidden">
					<myNavBar
						:height="navbar.common.height"
						:shadow="navbar.style.shadow"
						:border="navbar.style.border"
						:absolute="navbar.style.fixed"
						:backgroundColor="navbar.style.bgColor"
						:title="navbar.common.title"
						:titleColor="navbar.style.titleColor"
						:titleFontSize="navbar.style.titleFontSize"
						:leftText="navbar.common.backText"
						:leftColor="navbar.style.backTextColor"
						:leftIcon="navbar.style.backIcon"
						:leftFileName="navbar.style.backIconFileName"
						:leftIconParam="navbar.style.backIconParam"
						:leftImg="navbar.style.backImgUrl"
						:leftFontSize="navbar.style.leftFontSize"
						:rightText="navbar.common.rightText"
						:rightColor="navbar.style.rightTextColor"
						:rightIcon="navbar.style.rightIcon"
						:rightFileName="navbar.style.rightIconFileName"
						:rightIconParam="navbar.style.rightIconParam"
						:rightImg="navbar.style.rightImgUrl"
						:rightFontSize="navbar.style.rightFontSize"
						@clickLeft="navbarGoBack"
					></myNavBar>
				</block>

				<!-- 页面内容 -->
				<scroll-view class="myFlexArea" :scroll-x="false" scroll-y :scroll-top="scrollTop" :style="item.pageL + item.pageT + item.pageB + item.pageR" @scroll="handleScroll($event,index)" @scrolltolower="scrollLower($event,index)">
					<div :style="item.pageH" class="pageContent">
						<myPage ref="page" :level="1" parentCid="page" :pageConfig="item" :jsonData="item.page.content"></myPage>
					</div>
				</scroll-view>

				<!-- 浮动区域 -->
				<div class="floatArea" :style="'margin-top:'+item.navbarH+'px;margin-bottom:'+item.tabbarH+'px;'">
					<myPage ref="floatPage" parentCid="page" :pageConfig="item" :jsonData="item.page.float"></myPage>
					<template v-if="item.page.fixed">
						<div class="sideArea" :style="'width:'+item.leftW+'rpx;height:'+item.contentH+'px;top:0;left:0;'">
							<myPage ref="leftPage" parentCid="page" :pageConfig="item" :jsonData="item.page.fixed.left"></myPage>
						</div>
						<div class="sideArea" :style="'width:750rpx;height:'+item.topHNum+'px;top:0;left:0;'">
							<myPage ref="topPage" parentCid="page" :pageConfig="item" :jsonData="item.page.fixed.top"></myPage>
						</div>
						<div class="sideArea" :style="'width:'+item.rightW+'rpx;height:'+item.contentH+'px;top:0;left:'+(750-item.rightW)+'rpx;'">
							<myPage ref="rightPage" parentCid="page" :pageConfig="item" :jsonData="item.page.fixed.right"></myPage>
						</div>
						<div class="sideArea" :style="'width:750rpx;height:'+item.botH+'rpx;bottom:0;left:0;'">
							<myPage ref="botPage" parentCid="page" :pageConfig="item" :jsonData="item.page.fixed.bottom"></myPage>
						</div>
					</template>
				</div>
			</div>
		</block>

		<!-- tabbar -->
		<myTabbar ref="tabbar" @tabbarTap="changeTabActive" :comIndex="comIndex" :curPageCid="curPageCid"></myTabbar>

		<!-- 弹窗区域 -->
		<u-popup v-model="popupShow" mode="center" :mask-close-able="maskCloseAble" @touchmove="true" class="modelParser-popArea">
			<div v-if="popPage" :style="'width:'+popPage.popW+'rpx;height:'+popPage.popH+'rpx;'">
				<myPage ref="popPage" parentCid="page" :pageConfig="popPage" :jsonData="popPage.page.content"></myPage>
			</div>
		</u-popup>

		<!-- 日历组件 -->
		<m-calendar v-model="calendarShow" @change="calendarChange" :mode="calendarMode" :start-text="calendarStartText" :end-text="calendarEndText" :toolTip="calendarTooltip" :min-date="calendarMinDate" :max-date="calendarMaxDate" safe-area-inset-bottom></m-calendar>
	</div>
</template>

<script>
// import actLog from './libs/actLog'
import myNavBar from './importedCom/my-nav-bar/my-nav-bar.vue';
import myTabbar from './myCom/myTabbar.vue';
import myPage from './myPage';
import homePages from './libs/homePages';
import { triggerEvent, sendAjaxRequest, getKeyData, copy } from './libs/utils.js';
import widgetSet from './libs/widgetSet.js';
import variableChange from './libs/variableChange.js';
import getStorage from './libs/getStorage.js';
import handleDataProcess from './libs/handleDataProcess.js'
import statusBarHeight from './libs/statusBarHeight'
import windowHeight from './libs/windowHeight'
import safeArea from './libs/safeArea'
import getPageJson from './libs/getPageJson.js';
import handleStateMent from './libs/handleStateMent.js';
import debounce1 from './libs/debounce1.js';
import systemInfo from './libs/systemInfo.js';
export default {
	name: 'Home',
	components: {
		myPage,myNavBar,myTabbar
	},
	data(){
		return {
			pageData: {
				conData: [],
				appMenus: []
			},
			currentPageIndex: 0,
			curPageCid: '',
			createdTime: 0,
			childPages: [],
			popPage: null,
			popupShow: false,
			maskCloseAble: true,
			pageBroadNames: [],
			calendarMode: 'date',
			calendarShow: false,
			calendarStartText: '',
			calendarEndText: '',
			calendarStartVari: '',
			calendarEndVari: '',
			calendarTooltip: '',
			calendarPageCid: '',
			calendarMinDate: '',
			calendarMaxDate: '',
			calendarTargetEv: []
		};
	},
	props: {
		singPage: null,
		comIndex: null,
		scrollTop: {
			type: Number,
			default: 0
		}
	},
	inject: ['options'],
	methods: {
		pageInit(index,ifSamePageUpdate){
			// 每次刷新页面时，解绑全局广播
			this.pageBroadNames.forEach(name=>{
				uni.$off(name)
			})
			var ifFirstLoad = Boolean(this.$refs.page && this.$refs.page[index]);
			if(ifFirstLoad && this.$editMode){
				ifFirstLoad = false
				ifFirstLoad = ifSamePageUpdate
			}
			// 需要测试在非编辑器模式下，下拉刷新会不会导致页面执行两遍afterCreated
			this.pageStyle(index);
			this.calcCurPageIndex();
			// 注册页面事件
			var page = this.pageData.conData[index]
			this.initOnePage(page);
			// actLog({
			// 	shareLockCycle: 24,
			// 	pageCode: page.cid,
			// 	itemType: 'pageOpen',
			// 	itemCode: '1',
			// 	itemName: '页面加载事件',
			// 	actCode: '',
			// 	themeCode: '',
			// 	withLoc: true
			// })
			this.registerPop(this.pageData.conData)
			setTimeout(()=>{
				// 触发页面created，show等生命周期
				this.pageState('created');
				if(ifFirstLoad){
					this.$refs.page[index].afterCreated()
					this.$refs.floatPage[index].afterCreated()
					this.$refs.leftPage[index].afterCreated()
					this.$refs.topPage[index].afterCreated()
					this.$refs.rightPage[index].afterCreated()
					this.$refs.botPage[index].afterCreated()
				}
			})
		},
		calendarChange(e){
			var pages = this.pageData.conData.concat(this.childPages),arr = [];
			if(this.calendarMode === 'date'){
				arr.push({
					key: this.calendarStartVari,
					val: e.result
				})
			}else{
				var startDate = e.startDate,endDate = e.endDate;
				arr.push({
					key: this.calendarStartVari,
					val: startDate
				})
				arr.push({
					key: this.calendarEndVari,
					val: endDate
				})
			}
			pages.some(page=>{
				if(page.cid === this.calendarPageCid){
					arr.forEach(item=>{
						variableChange({
							page,
							variableName: item.key,
							data: item.val
						});
					})
					return true
				}
			})
			uni.$emit('eventCallback-' + this.calendarPageCid, this.calendarTargetEv)
		},
		registerPop(pages){
			pages.forEach(page=>{
				uni.$off('pop-'+page.cid)
				uni.$on('pop-'+page.cid,payload=>{
					this.maskCloseAble = payload.maskClose
					if(payload.type === 'open'){
						var ifHas = this.childPages.some(page=>{
							if(page.cid===payload.pageId){
								if(!this.popPage){
									this.popPage = page
								}else if(this.popPage.cid !== payload.pageId){
									this.popPage = page
									this.$refs.popPage.afterCreated()
								}
								this.popupShow = true
								return true
							}
						})
						if(!ifHas){
							this.popPage = null
							getPageJson(payload.pageId, '2').then(child => {
								var widgets = []
								child.page.content.some(widget=>{
									if(widget.type === 'layout'){
										widgets.push(widget)
										child.popW = widget.common.width
										child.popH = widget.common.height
										widget.common.x = 0
										widget.common.y = 0
										return true
									}
								})
								child.page.content = widgets
								child.isPop = true
								this.childPages.push(child)
								this.popPage = child
								this.childPageInit(child,page)
								this.popupShow = true
							})
						}
					}
				})
				uni.$off('closePop-'+page.cid)
				uni.$on('closePop-'+page.cid,payload=>{
					this.popupShow = false
					triggerEvent(payload.finish,{},this.options,page)
				})
			})
		},
		// 先注册本页面的事件
		initOnePage(pageConfig){
			console.log('注册页面事件');
			// 注册整个页面的其他事件,现在有sendAjax事件
			uni.$off('sendAjax-page-' + pageConfig.cid)
			uni.$on('sendAjax-page-' + pageConfig.cid, payload => {
				if (pageConfig.ajax && pageConfig.ajax.length > 0) {
					pageConfig.ajax.some(ajax => {
						if (ajax.cid === payload.ajaxCid) {
							sendAjaxRequest(ajax, this.options, 'page', pageConfig.variable, pageConfig.cid, pageConfig, payload.notToLogin).then(res => {
								// 处理ajax的数据导出
								if (ajax.transferKey) {
									ajax.transferKey.forEach(keyObj => {
										var targetData = getKeyData(keyObj.key, res.listData, 1);
										if (keyObj.transferType.indexOf('1') > -1) {
											variableChange({
												page: pageConfig,
												variableName: keyObj.variableName,
												data: targetData
											});
										}
										if (keyObj.transferType.indexOf('2') > -1) {
											// #ifdef H5
											window.localStorage.setItem(keyObj.storageName, targetData);
											// #endif
											// #ifdef MP
											uni.setStorageSync(keyObj.storageName, targetData);
											// #endif
										}
									});
								}
								// 网络请求的回调处理
								if(ajax.callBack){
									ajax.callBack.forEach(call=>{
										var result = handleStateMent(call.stateMent, res.listData)
										if(result){
											uni.$emit('eventCallback-' + pageConfig.cid, call.events)
										}
									})
								}
								// 对数据进行处理
								res.listData = handleDataProcess(res.listData, ajax.process);
								// 将数据绑定整理成属性修改
								var bindData = res.bindData.map(item => {
									return {
										type: 'attr',
										target: item.originKey
											.split('%krt_')
											.slice(0, -1)
											.join('%krt_'),
										attrList: [
											{
												attr: ['common', item.originKey.split('%krt_').slice(-1)[0]].join('%krt_'),
												target: getKeyData(item.bindKey, res.listData, 1)
											}
										]
									};
								});
								// 数据绑定利用属性修改事件来完成
								widgetSet({
									pageCid: pageConfig.cid,
									e: { list: bindData }
								});
							});
							return true;
						}
					});
				}
			})
			//注册整个页面的网络请求回调事件
			uni.$off('eventCallback-' + pageConfig.cid)
			uni.$on('eventCallback-' + pageConfig.cid, events => {
				var newE = pageConfig.event.filter(e => events.indexOf(e.cid)>-1);
				triggerEvent(newE, {}, this.options, pageConfig);
			})
			//注册整个页面的接收广播事件
			if (pageConfig.broadCast) {
				pageConfig.broadCast.forEach(broad => {
					// 记录下全局广播，便于在每次刷新页面时解绑
					if(this.pageBroadNames.indexOf(broad.name) === -1){
						this.pageBroadNames.push(broad.name)
					}
					uni.$on(broad.name, params => {
						//默认将广播传过来的数据保存到页面变量中
						for (var k in params) {
							variableChange({
								page: pageConfig,
								variableName: k,
								data: params[k]
							});
						}
						//增加延时是为了等待pageConfig传到页面组件中，不然组件中的pageConfig晚于页面中的pageConfig更新
						this.$nextTick(()=>{
							broad.events.forEach(eid => {
								if (pageConfig.event) {
									var newE = pageConfig.event.filter(e => e.cid === eid);
									triggerEvent(newE, {}, this.options, pageConfig);
								}
							});
						})
					});
				});
			}
			if (pageConfig.state) {
				//注册整个页面的监听登录状态的事件
				var loginState = pageConfig.state.filter(stateObj => stateObj.type === 'login');
				if (loginState.length > 0) {
					uni.$off('login-' + pageConfig.cid)
					uni.$on('login-' + pageConfig.cid, () => {
						console.log('接收到已登录事件');
						this.runState(pageConfig, 'login');
					});
				}
				var logoutState = pageConfig.state.filter(stateObj => stateObj.type === 'logout');
				if (logoutState.length > 0) {
					uni.$off('logout-' + pageConfig.cid)
					uni.$on('logout-' + pageConfig.cid, payload => {
						console.log('接收到未登录事件');
						this.runState(pageConfig, 'logout');
						this.$afterTokenError({dotToLogin: payload?payload.notToLogin:false})		// 在实际项目中有$afterTokenError这个方法
					});
				}
			}
			if(!this.$editMode){
				uni.$off('pageGap-' + pageConfig.cid)
				uni.$on('pageGap-' + pageConfig.cid, gap=>{
					this.pageData.conData.some((page,index)=>{
						if(page.cid === pageConfig.cid){
							this.pageStyle(index,gap)
							return true
						}
					})
				})
			}
			uni.$off('tabTitle-' + pageConfig.cid)
			uni.$on('tabTitle-' + pageConfig.cid, page => {
				var flag = this.childPages.some(child=>child.cid===page.cid)
				if(!flag){
					this.childPages.push(page)
				}
				this.childPageInit(page,pageConfig)
			});
			uni.$off('openCalendar-'+pageConfig.cid)
			uni.$on('openCalendar-'+pageConfig.cid,e=>{
				this.calendarMode = e.mode
				this.calendarStartText = e.startText
				this.calendarEndText = e.endText
				this.calendarTooltip = e.toolTip
				this.calendarStartVari = e.startVari
				this.calendarEndVari = e.endVari
				this.calendarPageCid = pageConfig.cid
				this.calendarMinDate = e.minDate
				this.calendarMaxDate = e.maxDate
				this.calendarTargetEv = e.confirmEv
				this.calendarShow = true
			})
		},
		pageState(state, pageConfig) {
			// 记录created的执行时间,当show与created短时间内都触发时,不执行show
			if(state === 'created'){
				this.createdTime = new Date().getTime()
			}else if(state === 'show'){
				var nowTime = new Date().getTime()
				if(nowTime - this.createdTime < 600){
					return
				}
			}
			console.log('执行了页面的生命周期', state);
			if (!pageConfig) {
				pageConfig = this.pageData.conData[this.currentPageIndex];
			}
			this.runState(pageConfig, state);
			if(!this.$editMode && state === 'created'){
				if(getStorage('token')){
					console.log('发送已登录事件');
					uni.$emit('login-' + pageConfig.cid)
				}else{
					console.log('发送未登录事件');
					uni.$emit('logout-' + pageConfig.cid)
				}
			}
		},
		runState(pageConfig, state, scrollTop) {
			if (pageConfig.state) {
				var curState = pageConfig.state.filter(stateObj => stateObj.type === state);
				curState.forEach(stateObj => {
					// if (state !== 'pageScroll' || (state === 'pageScroll' && stateObj.minScroll < scrollTop)) {
						stateObj.events.forEach(eid => {
							if (pageConfig.event) {
								var newE = []
								pageConfig.event.forEach(e =>{
									if(e.cid === eid){
										// 先将事件复制一份,因为下面代码会修改事件对象本身
										var cloneObj = copy(e)
										// 如果是触发页面的created生命周期,则列表/轮播图等组件的ajax无需手动调用
										// 未来如果属性修改事件中的刷新列表数据被广泛应用了,则created时也无需执行刷新列表数据
										if(state === 'created' && e.type === 'sendAjax'){
											cloneObj.ajaxIds = cloneObj.ajaxIds.filter(id=>id.match(/(%krt_)/g).length === 1)
										}
										// 如果是通过show生命周期触发的sendAjax事件,则如果需要登录且未登录/token失效时不主动登录
										if(state === 'show' && e.type === 'sendAjax'){
											cloneObj.notToLogin = true
										}
										// 在编辑器模式下，不执行弹窗、定时器、模态框等事件
										if(this.$editMode && (e.type === 'popup' || e.type === 'timer' || e.type === 'modal')){}else{
											newE.push(cloneObj)
										}
									}
								});
								triggerEvent(newE, {}, this.options, pageConfig);
							}
						});
					// }
				});
			}
		},
		childPageInit(child,parent){
			// 打开标签页中的子页面时,先对比一下父子页面中共同的变量,将父页面中同名变量值更新到子页面中去
			// 当子页面打开时，肯定这个子页面的created状态的事件中肯定也会用到这几个变量
			if(child.variable && parent.variable){
				child.variable.forEach(vari => {
					parent.variable.some(vari2 => {
						if(vari2.keyName === vari.keyName){
							vari.val = vari2.val
							return true
						}
					})
				})
			}
			this.initOnePage(child)
			this.registerPop([].concat(child))
			setTimeout(()=>{
				this.pageState('created', child);
			})
		},
		// 页面滚动时
		handleScroll(e,index) {
			this.$refs.page[index].scrollTop = e.detail.scrollTop;
			this.$refs.page[index].scrollTopChange();
			// var pageConfig = this.pageData.conData[index];
			// this.runState(pageConfig, 'pageScroll', detail.scrollTop);
		},
		lowerHandler(index){
			return ()=>{
				var pageConfig = this.pageData.conData[index];
				uni.$emit('scrollToBot-' + pageConfig.cid);
				// 不仅要通知父页面中的所有列表,也要通知子页面中的列表
				this.childPages.forEach(page=>{
					if(!page.isPop){
						uni.$emit('scrollToBot-' + page.cid);
					}
				})
			}
		},
		//页面滚动到底部时
		scrollLower(e,index) {
			var fn = this.lowerHandler(index)
			debounce1(fn,500,true)
		},
		// 计算当前选中页索引
		calcCurPageIndex(){
			if (this.singPage) {
				this.currentPageIndex = 0;
			}else{
				var originSelectIndex = this.pageData.appMenus[0].common.originSelectIndex || 0;
				this.currentPageIndex = this.outputActiveIndex(originSelectIndex);
			}
			this.curPageCid = this.pageData.conData[this.currentPageIndex].cid
		},
		outputActiveIndex(index) {
			var calcIndex = null,pageId = null,link = this.pageData.appMenus[0].common.links[index];
			if (link) {
				pageId = link.pageId;
			}
			if (pageId) {
				this.pageData.conData.some((item, i) => {
					if (item.cid === pageId) {
						calcIndex = i;
						return true;
					}
				});
			}
			return calcIndex;
		},
		tabbarInit(){
			this.$refs.tabbar.tabbar = this.pageData.appMenus[0]
		},
		// 切换激活的页面
		changeTabActive(index, cid, broadP) {
			var ifHas = this.pageData.conData.some(page => page.cid === cid);
			if (!ifHas) {
				this.$emit('tabChange', cid, broadP);
				this.$nextTick(() => {
					this.afterChangeTabActive(ifHas);
				});
			} else {
				this.currentPageIndex = this.outputActiveIndex(index);
				this.afterChangeTabActive(ifHas);
			}
		},
		afterChangeTabActive(ifHas) {
			var page = this.pageData.conData[this.currentPageIndex];
			if (!page) {
				return
			}
			if (ifHas) {
				this.pageState('show');
			}
		},
		navbarGoBack() {
			if (getCurrentPages().length === 1) {
				uni.reLaunch({
					url: '/' + homePages[0]
				})
			} else {
				uni.navigateBack()
			}
		},
		pageStyle(index,gap) {
			var page = this.pageData.conData[index];
			var pH = '42800px;'
			if (!this.$editMode) {
				pH = (page.pageHeight + (typeof gap === 'number' ? gap : 0)) + 'rpx;'
			}
			this.$set(page,'pageH','height:' + pH)
			this.$set(page,'pageR','margin-right:' + page.rightW + 'rpx;')
			this.$set(page,'pageL','margin-left:' + page.leftW + 'rpx;')
			var pageBg = 'background-color:' + page.bgColor + ';background-image:url(' + page.bgImg + ');'
			if(page.bgMode === 'stretch' || !page.bgMode){
				pageBg += 'background-size:100%';
			}
			this.$set(page,'pageBg',pageBg)
			var navbarH = 0
			if(page.page.navbar.length > 0){
				navbarH = uni.upx2px(page.page.navbar[0].common.height) + statusBarHeight
				this.$set(page,'topHNum',uni.upx2px(page.topH || 0))
			}else if(page.topH > 0){
				this.$set(page,'topHNum',uni.upx2px(page.topH || 0) + statusBarHeight)
			}
			this.$set(page,'pageT','margin-top:' + page.topHNum + 'px;')
			this.$set(page,'navbarH',navbarH)
			var tabbarH = 0
			if(!this.singPage && this.pageData.appMenus.length > 0 && this.pageData.appMenus[0].common.links.some(link=>link.pageId===page.cid)){
				tabbarH = uni.upx2px(this.pageData.appMenus[0].common.height)
			}
			var botSaveAreaH = 0;
			// #ifndef MP-ALIPAY
			botSaveAreaH = windowHeight - safeArea.height - safeArea.top
			// #endif
			// #ifdef MP-ALIPAY
			if(systemInfo.model.indexOf("iPhone X") > -1 || systemInfo.model.indexOf("iPhone 1") > -1){
				botSaveAreaH = 34
			}
			// #endif
			tabbarH += botSaveAreaH
			this.$set(page,'tabbarH',tabbarH)
			if(this.singPage){
				this.$set(page,'pageB','margin-bottom:' + (tabbarH+uni.upx2px(page.botH||0)) + 'px;')
			}else{
				this.$set(page,'pageB','margin-bottom:' + page.botH + 'rpx;')
			}
			var contentH = windowHeight - navbarH - tabbarH
			this.$set(page,'contentH',contentH)
		}
	}
};
</script>
<style lang="less" scoped>
.appContainer{
	width: 100vw;
	height: 100vh;
	display: flex;
	flex-direction: column;
	.pageCon{
		flex: 1;
		display: flex;
		flex-direction: column;
		overflow: hidden;
		display: none;
		position: relative;
		&.show{
			display: flex;
		}
		.myFlexArea{
			flex: 1;
			position: relative;
			width: auto;
			.pageContent{
				width: 100%;
				position: absolute;
			}
		}
		.pageBg{
			position: absolute;
			width: 100%;
			height: 100%;
			left: 0;
			top: 0;
			background-repeat: no-repeat;
			background-position: center top;
			&.tile{
				background-size: 100% auto;
				background-repeat: no-repeat;
				background-position: left top;
			}
		}
		.floatArea{
			position: fixed;
			width: 0;
			left: 0;
			top: 0;
			bottom: 0;
			z-index: 900;
			.sideArea{
				position: absolute;
			}
		}
	}
}
</style>
